﻿using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using NLog.Config;
using Shell32;
using System.IO;
using System.Threading;
using System.Reflection;

namespace BlobStroage
{
    public partial class CloudBlob : Form
    {
        public CloudBlob()
        {
            BlobContainerManager();
            GetCloudBlobClient();
            InitializeComponent();
        }

        Microsoft.WindowsAzure.Storage.Blob.CloudBlobClient blobClient;
        Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer blobContainer;

        private string connectString = System.Configuration.ConfigurationManager.ConnectionStrings["StorageConnectionString"].ConnectionString;
        private CloudStorageAccount storageAccount;


        /// <summary>
        /// 获取Account
        /// </summary>
        public void BlobContainerManager()
        {
            storageAccount = CloudStorageAccount.Parse(connectString);
        }

        /// <summary>
        /// 获取CloudBlobClient
        /// </summary>
        /// <returns></returns>
        public void GetCloudBlobClient()
        {
            blobClient = storageAccount.CreateCloudBlobClient();
        }

        /// <summary>
        /// 创建一个新的blob container   
        /// container name 不允许出现大写字符
        /// </summary>
        /// <param name="containerName"></param>
        public CloudBlobContainer CreateCloudBlobContainer(String containerName)
        {
            containerName = containerName.ToLower();
            blobContainer = blobClient.GetContainerReference(containerName);

            blobContainer.CreateIfNotExists();

            blobContainer.SetPermissions(
                new BlobContainerPermissions
                {
                    PublicAccess = BlobContainerPublicAccessType.Blob
                });

            return blobContainer;
        }

        /// <summary>
        /// 上传文件
        /// GetBlockBlobReference(name)   name为 文件在cantainer里的名称
        /// </summary>
        public void UploadBlobToBlobContainer(String containerName)
        {
            CreateCloudBlobContainer(containerName);

            String filePath = this.txt_FileName.Text;

            if (filePath.Length != 0 || filePath != "")
            {
                String fileName = filePath.Substring(filePath.LastIndexOf('\\') + 1).ToLower().Trim();
                String blobName = Guid.NewGuid().ToString("D") + "-" + fileName;
                CloudBlockBlob blockblob = blobContainer.GetBlockBlobReference(blobName);

                using (var fileStream = System.IO.File.OpenRead(filePath))
                {
                    blockblob.UploadFromStream(fileStream);
                }
                SetFileMetadata(blockblob, filePath);
                listBox1.Items.Add(blobName);
            }
        }

        /// <summary>
        /// 获取所有的blobs
        /// </summary>
        /// <param name="containerName"></param>
        /// <returns></returns>
        private List<Object> GetAllBlobs(String containerName)
        {
            List<Object> list = new List<Object>();

            CloudBlobContainer container = CreateCloudBlobContainer(containerName);

            foreach (IListBlobItem item in container.ListBlobs(null, false))
            {
                if (item.GetType() == typeof(CloudBlockBlob))
                {
                    CloudBlockBlob blob = (CloudBlockBlob)item;

                    list.Add(blob);
                }
                if (item.GetType() == typeof(CloudPageBlob))
                {
                    CloudPageBlob blob = (CloudPageBlob)item;
                    list.Add(blob);
                }
                if (item.GetType() == typeof(CloudBlobDirectory))
                {
                    CloudBlobDirectory blob = (CloudBlobDirectory)item;
                    list.Add(blob);
                }
            }
            return list;
        }

        /// <summary>
        /// Del Blob
        /// </summary>
        /// <param name="containerName"></param>
        /// <param name="blobName"></param>
        private void DelBlobs(String containerName, String blobName)
        {
            CloudBlobContainer container = CreateCloudBlobContainer(containerName);

            CloudBlockBlob blockblob = container.GetBlockBlobReference(blobName);
            blockblob.Delete();
            listBox1.Items.Remove(blobName);
        }

        /// <summary>
        /// Set blob Metadata
        /// </summary>
        /// <param name="blob"></param>
        /// <param name="filePath"></param>
        private void SetFileMetadata(CloudBlockBlob blob, String filePath)
        {
            Folder folder = GetFolder(filePath);
            FolderItem item = GetFolderItem(folder, filePath);

            String suffix = filePath.Substring(filePath.LastIndexOf('.') + 1);

            blob.Metadata.Add(FileMetadata.fileName, folder.GetDetailsOf(item, 0));
            blob.Metadata.Add(FileMetadata.fileSize, folder.GetDetailsOf(item, 1).ToLower());

            if (suffix.ToLower().Trim() == "mp4" || suffix.ToLower().Trim() == "wmv")
            {
                blob.Metadata.Add(FileMetadata.fileWidth, folder.GetDetailsOf(item, 285));
                blob.Metadata.Add(FileMetadata.fileHeight, folder.GetDetailsOf(item, 283));
            }
            if (suffix.ToLower().Trim() == "jpg" || suffix.ToLower().Trim() == "png")
            {
                //folder.GetDetailsOf(item, 162) 前面有个非法字符---单个char，提示非法字符 so we must Substring
                blob.Metadata.Add(FileMetadata.fileWidth, folder.GetDetailsOf(item, 162).Substring(1));
                blob.Metadata.Add(FileMetadata.fileHeight, folder.GetDetailsOf(item, 164).Substring(1));
            }
            blob.SetMetadata();
        }

        /// <summary>
        /// 获取当前路径下面的文件夹对象
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        public Folder GetFolder(String filePath)
        {

            //set Embed Interop Types to false  
            //初始化Shell接口  
            Shell32.Shell shell = new Shell32.ShellClass();
            //获取文件所在父目录对象  
            Folder folder = shell.NameSpace(filePath.Substring(0, filePath.LastIndexOf('\\')));
            return folder;
        }

        /// <summary>
        /// 根据文件路径，文件folder对象的Item对象
        /// </summary>
        /// <param name="folder"></param>
        /// <param name="filePath"></param>
        /// <returns></returns>
        public FolderItem GetFolderItem(Folder folder, string filePath)
        {
            return folder.ParseName(filePath.Substring(filePath.LastIndexOf('\\') + 1));
        }

        /// <summary>
        /// operator folder
        /// </summary>
        /// <param name="path1"></param>
        /// <param name="path2"></param>
        /// <param name="path3"></param>
        /// <returns></returns>
        public List<String> GetThreeSame(String path1, String path2, String path3)
        {
            List<string> list1 = new List<string>();
            List<string> list2 = new List<string>();
            List<string> list3 = new List<string>();

            DirectoryInfo folder1 = new DirectoryInfo(path1);
            DirectoryInfo folder2 = new DirectoryInfo(path2);
            DirectoryInfo folder3 = new DirectoryInfo(path3);

            List<string> same = new List<string>();
            List<string> allsame = new List<string>();
            List<string> different1 = new List<string>();
            List<string> different2 = new List<string>();
            List<string> different3 = new List<string>();

            foreach (DirectoryInfo f in folder1.GetDirectories())
            {
                list1.Add(f.Name);
            }
            foreach (DirectoryInfo f in folder2.GetDirectories())
            {
                list2.Add(f.Name);
            }
            foreach (DirectoryInfo f in folder3.GetDirectories())
            {
                list3.Add(f.Name);
            }

            for (int i = 0; i < list1.Count; i++)
            {
                for (int j = 0; j < list2.Count; j++)
                {
                    if (list1[i] == list2[j])
                    {
                        same.Add(list1[i]);
                    }
                }
            }

            for (int i = 0; i < same.Count; i++)
            {
                for (int j = 0; j < list3.Count; j++)
                {
                    if (same[i] == list3[j])
                    {
                        allsame.Add(same[i]);
                    }
                }
            }

            for (int i = 0; i < allsame.Count; i++)
            {
                listBox3.Items.Add(allsame[i]);
            }

            for (int i = 0; i < list1.Count; i++)
            {
                bool isExist = false;
                for (int j = 0; j < allsame.Count; j++)
                {
                    if (list1[i] == allsame[j])
                    {
                        isExist = true;
                        break;
                    }
                }
                if (!isExist)
                {
                    different1.Add(list1[i]);
                    listBox4.Items.Add(list1[i]);
                }
            }

            for (int i = 0; i < list2.Count; i++)
            {
                bool isExist = false;
                for (int j = 0; j < allsame.Count; j++)
                {
                    if (list2[i] == allsame[j])
                    {
                        isExist = true;
                        break;
                    }
                }
                if (!isExist)
                {
                    different2.Add(list2[i]);
                    listBox5.Items.Add(list2[i]);
                }
            }

            for (int i = 0; i < list3.Count; i++)
            {
                bool isExist = false;
                for (int j = 0; j < allsame.Count; j++)
                {
                    if (list3[i] == allsame[j])
                    {
                        isExist = true;
                        break;
                    }
                }
                if (!isExist)
                {
                    different3.Add(list3[i]);
                    listBox6.Items.Add(list3[i]);
                }
            }

            return allsame;
        }

        /// <summary>
        /// get blob Perproty
        /// </summary>
        /// <param name="blob"></param>
        /// <returns></returns>
        public String GetBlobPerproty(Microsoft.WindowsAzure.StorageClient.CloudBlob blob)
        {
            String result = "";
            string url = "http://evsdev1.cloudapp.net/api/assetdownload/";
            String containerName = blob.Container.Name;
            String blobname = blob.Name;

            if (blobname.IndexOf('-') == -1 || containerName.IndexOf('-') == -1)
            {
                return "";
            }

            String container_1 = containerName.Substring(0, containerName.IndexOf('-'));
            String container_2 = containerName.Substring(containerName.IndexOf('-') + 1);

            String blobname_1 = blobname.Substring(0, blobname.IndexOf('-'));
            String blobname_2 = blobname.Substring(blobname.IndexOf('-') + 1);

            result = url + container_1 + "/" + container_2 + "/" + blobname_1 + "/" + blobname_2;
            return result;
        }

        /// <summary>
        /// http://evsdev1.cloudapp.net/api/assetdownload/academy/joelfolder1/joel/seaweed.wm
        /// </summary>
        /// <param name="blob"></param>
        /// <returns></returns>
        public String test(Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob blob)
        {
            String result = "";
            String url = "http://evsdev1.cloudapp.net/api/assetdownload/";
            String blobname = blob.Name;
            String containerName = blob.Container.Name;
            if (blobname.IndexOf('-') == -1 || containerName.IndexOf('-') == -1)
            {
                return "";
            }

            String container_1 = containerName.Substring(0, containerName.IndexOf('-'));
            String container_2 = containerName.Substring(containerName.IndexOf('-') + 1);

            String blobname_1 = blobname.Substring(0, blobname.IndexOf('-'));
            String blobname_2 = blobname.Substring(blobname.IndexOf('-') + 1);

            result = url + container_1 + "/" + container_2 + "/" + blobname_1 + "/" + blobname_2;
            return result;
        }

        /// <summary>
        /// download the blob
        /// </summary>
        /// <param name="blobName"></param>
        public void DownLoadBlob(string blobName)
        {
            CreateCloudBlobContainer("mytestblob");
            string path = Assembly.GetExecutingAssembly().Location;
            path = path.Substring(0, path.IndexOf("\\bin")) + @"\\DownLoadBlobs\\" + blobName;
            CloudBlockBlob blockBlob = blobContainer.GetBlockBlobReference(blobName);
            using (var fileStream = System.IO.File.OpenWrite(path))
            {
                blockBlob.DownloadToStream(fileStream);
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            String containerName = "mytest-blob";
            UploadBlobToBlobContainer(containerName);
        }

        private void button3_Click(object sender, EventArgs e)
        {
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                txt_FileName.Text = openFileDialog1.FileName;
                openFileDialog1.InitialDirectory = System.IO.Path.GetDirectoryName(openFileDialog1.FileName);
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            this.listBox1.Items.Clear();
            this.listBox2.Items.Clear();
            List<Object> list = GetAllBlobs("mytestblob");
            if (list.Count != 0 || list != null)
            {
                foreach (Object obj in list)
                {
                    if (obj.GetType().Name == "CloudBlockBlob")
                    {
                        CloudBlockBlob blob = (CloudBlockBlob)obj;

                        //读取属性必须先Fethch
                        blob.FetchAttributes();

                        this.listBox1.Items.Add(blob.Name);

                        this.listBox2.Items.Add(blob.Metadata["filename"]);

                    }
                    if (obj.GetType().Name == "CloudPageBlob")
                    {
                        CloudPageBlob blob = (CloudPageBlob)obj;
                        this.listBox1.Items.Add(blob.Name);
                        this.listBox2.Items.Add(blob.Uri);
                    }
                    if (obj.GetType().Name == "CloudBlobDirectory")
                    {
                        CloudBlobDirectory blob = (CloudBlobDirectory)obj;
                        this.listBox1.Items.Add(blob.Prefix);
                        this.listBox2.Items.Add(blob.Uri);
                    }
                }
            }
        }

        private void button4_Click(object sender, EventArgs e)
        {
            NlogForm f = new NlogForm();
            f.ShowDialog();
        }

        private void button5_Click(object sender, EventArgs e)
        {
            DelBlobs("mytestblob", this.listBox1.SelectedItem.ToString());
        }

        private void button6_Click(object sender, EventArgs e)
        {
            //CloudPerformanceCounter f = new CloudPerformanceCounter();
            //f.ShowDialog();
        }

        private void button7_Click(object sender, EventArgs e)
        {
            String path1 = @"D:\bugsys\BlobStroage\CompareFolders\TestA";
            String path2 = @"D:\bugsys\BlobStroage\CompareFolders\TestB";
            String path3 = @"D:\bugsys\BlobStroage\CompareFolders\TestC";

            List<string> sameFolders = GetThreeSame(path1, path2, path3);
        }

        private void button8_Click(object sender, EventArgs e)
        {
            List<string> list1 = new List<string>();
            List<string> list2 = new List<string>();
            List<string> list3 = new List<string>();
            List<string> listAll = new List<string>();

            String path1 = @"D:\bugsys\BlobStroage\CompareFolders\TestA";
            String path2 = @"D:\bugsys\BlobStroage\CompareFolders\TestB";
            String path3 = @"D:\bugsys\BlobStroage\CompareFolders\TestC";
            DirectoryInfo folder1 = new DirectoryInfo(path1);
            DirectoryInfo folder2 = new DirectoryInfo(path2);
            DirectoryInfo folder3 = new DirectoryInfo(path3);

            List<string> same = GetThreeSame(path1, path2, path3);

            foreach (DirectoryInfo f in folder1.GetDirectories())
            {
                list1.Add(f.Name);
                listAll.Add(f.Name);
            }
            foreach (DirectoryInfo f in folder2.GetDirectories())
            {
                list2.Add(f.Name);
                listAll.Add(f.Name);
            }
            foreach (DirectoryInfo f in folder3.GetDirectories())
            {
                list3.Add(f.Name);
                listAll.Add(f.Name);
            }


            for (int i = 0; i < listAll.Count; i++)
            {
                listBox7.Items.Add(listAll[i]);
            }


            for (int i = 0; i < listAll.Count; i++)
            {
                bool isExist1 = false;
                for (int j = 0; j < list1.Count; j++)
                {
                    if (listAll[i] == list1[j])
                    {
                        isExist1 = true;
                        listBox8.Items.Add("True");
                        break;
                    }
                }
                if (!isExist1)
                {
                    listBox8.Items.Add("False");
                }

                bool isExist2 = false;
                for (int j = 0; j < list2.Count; j++)
                {
                    if (listAll[i] == list2[j])
                    {
                        isExist2 = true;
                        listBox9.Items.Add("True");
                        break;
                    }
                }
                if (!isExist2)
                {
                    listBox9.Items.Add("False");
                }

                bool isExist3 = false;
                for (int j = 0; j < list3.Count; j++)
                {
                    if (listAll[i] == list3[j])
                    {
                        isExist3 = true;
                        listBox10.Items.Add("True");
                        break;
                    }
                }
                if (!isExist3)
                {
                    listBox10.Items.Add("False");
                }
            }
        }

        private void button9_Click(object sender, EventArgs e)
        {
            Threads f = new Threads();
            f.ShowDialog();
        }

        private void button10_Click(object sender, EventArgs e)
        {
            CloudTable f = new CloudTable();
            f.ShowDialog();
        }

        private void button11_Click(object sender, EventArgs e)
        {
            List<Object> list = GetAllBlobs("mytest-blob");

            CloudBlockBlob blob = (CloudBlockBlob)list[0];
            string temp = test(blob);
        }

        private void button12_Click(object sender, EventArgs e)
        {
            string name = this.listBox1.SelectedItem.ToString();
            DownLoadBlob(name);
        }
    }
}
